#include "StdAfx.h"
#include "SdpProcessor.h"


CSdpProcessor::CSdpProcessor(CSoapCore::CSoapCall* pSoapCall):
 m_pSdpOffer(NULL)
,m_pSdpAnswer(NULL)
,m_pSoapCall(pSoapCall)
,m_pSoapCore(pSoapCall->m_pSoapCore)
{
}

CSdpProcessor::~CSdpProcessor(void)
{
}

string CSdpProcessor::GetOfferSdp()
{
	char *tmp;
	/* add audio codecs */
	m_pSdpOffer = CreateSdpGenerateTemplate();
    m_nIncb = 1;

	SetAudioOffer();
	//if (sdph->set_video_codecs != NULL)
	//	sdph->set_video_codecs (ctx);

	m_nIncb = 0;
	sdp_message_to_str(m_pSdpOffer,&tmp);
	m_strOffer = tmp;
	return m_strOffer;
}

// generate a template sdp 
sdp_message_t* CSdpProcessor::CreateSdpGenerateTemplate()
{
	sdp_message_t *pLocal;
	sdp_message_init (&pLocal);

	string strNetIPType = string::npos == m_strLocalIp.find(':')?"IP4":"IP6";

	sdp_message_v_version_set (pLocal, osip_strdup ("0"));
	sdp_message_o_origin_set (pLocal, osip_strdup (m_strUserName.c_str()),
		osip_strdup ("123456"), osip_strdup ("654321"),
		osip_strdup ("IN"), osip_strdup (strNetIPType.c_str()),
		osip_strdup (m_strLocalIp.c_str()));

	sdp_message_s_name_set (pLocal, osip_strdup ("xSoap  conversation"));
	sdp_message_c_connection_add (pLocal, -1,
		osip_strdup ("IN"), osip_strdup (strNetIPType.c_str()),
		osip_strdup (m_strLocalIp.c_str()), NULL, NULL);
	sdp_message_t_time_descr_add (pLocal, osip_strdup ("0"), osip_strdup ("0"));

	return pLocal;
}

/* these are the SdpHandler callbacks: we are called in to be aware of the content
of the SDP messages exchanged */

void CSdpProcessor::SetAudioOffer()
{
	CSdpPayload sdpPayload;
	CMediaManager::CArrayPayloadTypePtr arrayAudioPTPtr = m_pSoapCore->m_cMediaManager.GetAudioCodes();
	for (CMediaManager::CArrayPayloadTypePtr::iterator it = arrayAudioPTPtr.begin(); it != arrayAudioPTPtr.end(); ++it)
	{
		CPayloadTypePtr spPT(*it);

		if (spPT.IsEnable())
		{	
			sdpPayload.m_str_a_rtpmap = string(spPT->mime_type) + "/" + SoapUtil::int_to_str(spPT->clock_rate) + "/1";
			sdpPayload.m_nPaylodType = rtp_profile_get_payload_number_from_rtpmap(m_pSoapCore->m_cMediaManager.m_pLocalRtpProfile,sdpPayload.m_str_a_rtpmap.c_str()); 

			sdpPayload.m_nLocalPort = (m_pSoapCall->m_cAudioParams.m_nNatdPort > 0) ?   \
				                              m_pSoapCall->m_cAudioParams.m_nNatdPort : \
			                                  m_pSoapCore->m_configRtp.m_nAudioRtpPort;

			if (strcasecmp(spPT->mime_type,"iLBC") == 0 )
			{
				sdpPayload.m_str_a_fmtp = "ptime=30";
			}

			AddPayloadToAdpMsg(sdpPayload,"audio");
		}

	}
	

	// add telephone-event payload
	sdpPayload.m_nPaylodType = rtp_profile_get_payload_number_from_mime(m_pSoapCore->m_cMediaManager.m_pLocalRtpProfile,"telephone-event");
	sdpPayload.m_str_a_rtpmap = "telephone-event/8000";
	sdpPayload.m_str_a_fmtp   = "0-11";
	//if (lc->dw_audio_bw>0) payload.b_as_bandwidth=lc->dw_audio_bw;
	AddPayloadToAdpMsg(sdpPayload,"audio");

}

void CSdpProcessor::AddRelayInfo(sdp_message_t *sdp, int mline, const char *relay, const char *relay_session_id){

	if (relay) sdp_message_a_attribute_add(sdp, mline,
		osip_strdup ("relay-addr"),osip_strdup(relay));
	if (relay_session_id) sdp_message_a_attribute_add(sdp, mline,
		osip_strdup ("relay-session-id"), osip_strdup(relay_session_id));
}

char * CSdpProcessor::int_2char(int a)
{
	char *p = (char*)osip_malloc(32);
	snprintf(p,32,"%i",a);
	return p;
}

// to add payloads to the offer, must be called inside the write_offer callback */
void CSdpProcessor::AddPayloadToAdpMsg (CSdpPayload& payload, string strMedia)
{
	if (!m_nIncb)
	{
		Soap_Error("You must not call sdp_context_add_*_payload outside the write_offer callback!");
		//abort ();
	}

	if (payload.m_strProto.empty())
	{
		payload.m_strProto = "RTP/AVP";
	}

	/*printf("payload->line=%i payload->pt=%i\n",payload->line, payload->pt);*/
	if (sdp_message_m_media_get (m_pSdpOffer, payload.m_nLineIdx) == NULL)
	{
		/*printf("Adding new mline %s \n",media);*/
		/* need a new line */
		sdp_message_m_media_add (m_pSdpOffer, osip_strdup (strMedia.c_str()),
			int_2char (payload.m_nLocalPort), NULL,
			osip_strdup ( payload.m_strProto.c_str()));

		if (!m_strRelay.empty())
		{
			AddRelayInfo(m_pSdpOffer, payload.m_nLineIdx,m_strRelay.c_str(),m_strRelaySessionId.c_str());
		}
	}

    string strAttr;
	sdp_message_m_payload_add (m_pSdpOffer, payload.m_nLineIdx, int_2char ( payload.m_nPaylodType));
	if (! payload.m_str_a_rtpmap.empty())
	{	
		strAttr = SoapUtil::int_to_str(payload.m_nPaylodType) + " " + payload.m_str_a_rtpmap;
		sdp_message_a_attribute_add (m_pSdpOffer, payload.m_nLineIdx,osip_strdup ("rtpmap"), osip_strdup(strAttr.c_str()));
	}

	if (! payload.m_str_a_fmtp.empty())
	{
		strAttr = SoapUtil::int_to_str(payload.m_nPaylodType) + " " + payload.m_str_a_fmtp;
		sdp_message_a_attribute_add (m_pSdpOffer,  payload.m_nLineIdx,osip_strdup ("fmtp"), osip_strdup(strAttr.c_str()));
	}

	if ( payload.m_nBAsBandwidth != 0)
	{	
		if (sdp_message_bandwidth_get(m_pSdpOffer, payload.m_nLineIdx,0) == NULL)
		{
			sdp_message_a_attribute_add (m_pSdpOffer,  payload.m_nLineIdx,osip_strdup ("AS"), osip_strdup(SoapUtil::int_to_str(payload.m_nBAsBandwidth).c_str()));
		}
	}

}
